/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.tapestry.elfinder.services;

import java.io.ByteArrayOutputStream;
import java.io.File;

import org.apache.tapestry5.upload.services.UploadedFile;
import org.libermundi.tapestry.elfinder.exception.ElFinderException;
import org.libermundi.tapestry.elfinder.exception.VolumeIOException;

/**
 * Represent a "Volume" for ElFinder. A Volume is like a Drive mounted in the File Browser
 * One ElFinder can provide access to several {@link Volume}s
 * 
 * The {@link Volume} is responsible for all I/O operations and Security checkings
 * 
 * @author Martin Papy
 *
 */
public interface Volume {
	/**
	 * @return the Root Directory matching this specific {@link Volume}
	 */
	public File getBasePath(); 
	
	/**
	 * 
	 * @return the corresponding URL to the Root Directory
	 */
	public String getBaseUrl();

	/**
	 * 
	 * @param file
	 * @return
	 * @throws VolumeIOException 
	 */
	public String getClientUrl(File file) throws VolumeIOException;
	
	/**
	 * 
	 * @param hash
	 * @return
	 * @throws VolumeIOException 
	 */
	public String getClientUrl(String hash) throws VolumeIOException;
	
	/**
	 * Look for a File or Directory based on the provided hash.
	 * The search is performed in the whole volume. 
	 * @param targetHash
	 * @return the corresponding {@link File} or <code>null</code>
	 * @throws VolumeIOException 
	 */
	public File getFileFromHash(String targetHash) throws VolumeIOException;
	
	/**
	 * Look for a File or Directory based on the provided hash.
	 * The search is performed within the specified Directory or its subfolders. 
	 * @param targetHash
	 * @param folder
	 * @return the corresponding {@link File} or <code>null</code>
	 * @throws VolumeIOException 
	 */
	File getFileFromHash(String targetHash, File folder) throws VolumeIOException;	
	
	/**
	 * Generate a Hash compatible with ElFinder specifications ( volumeId + _  + hash )
	 * @param file
	 * @return
	 */
	public String hash(File path);
	
	/**
	 * Return the ID of the Volume. Must be UNIQUE.
	 * @return a String representing the ID
	 */
	public String getId();
	
	/**
	 * Return true if the path represents either a Directory or is a File for which the
	 * extension is allowed in this {@link Volume}
	 * @param file
	 * @return
	 */
	public boolean isAllowed(File path);

	/**
	 * Return true if the path represents either a Directory or is a file for which the
	 * extension is allowed in this {@link Volume} and matches the {@link FileType}
	 * @param file
	 * @param type
	 * @return
	 */
	public boolean isAllowed(File path, FileType type);
	/**
	 * Return true if the path represents either a Directory or is a File for which the
	 * extension is allowed in this {@link Volume}
	 * @param file
	 * @return
	 */

	public boolean isAllowed(String filename);

	/**
	 * Return true if the filename extension is allowed in this
	 * {@link Volume} and matches the {@link FileType}
	 * @param filename
	 * @param type
	 * @return
	 */
	public boolean isAllowed(String filename, FileType type);
	
	/**
	 * Add a list of extension to be allowed on this Volume. Extension are case insensitive
	 * @param type
	 * @param extensions 
	 */
	public void allowExtension(FileType type, String... extensions);

	/**
	 * Create a new empty file in the specified directory
	 * @param fileName
	 * @param existingDir
	 * @return the newly created {@link File}
	 * @throws VolumeIOException 
	 */
	public File getNewFile(String fileName, File existingDir) throws VolumeIOException;
	
	/**
	 * 
	 * @param fileName
	 * @param existingDir
	 * @param makeUnique
	 * @return
	 * @throws ElFinderException
	 * @throws VolumeIOException 
	 */
	public File getNewFile(String fileName, File existingDir, boolean makeUnique) throws ElFinderException, VolumeIOException;

	/**
	 * Check if the filename provided complies with the naming rule of the {@link Volume}
	 * @param fileName
	 * @return <code>true</code> when the name is compliant
	 */
	public boolean isValidFilename(String fileName);

	/**
	 * @return
	 */
	public String getAlias();

	/**
	 * @param file
	 * @return
	 */
	public boolean isSpecialDir(File file);

	
	public boolean isOperationAllowed(File file, VolumeOperation operation);

	/**
	 * @param file
	 * @return
	 * @throws VolumeIOException 
	 */
	public String getRelativeUrlPath(File file) throws VolumeIOException;

	/**
	 * @return
	 */
	public String getPathSeparator();

	/**
	 * @param f
	 * @return
	 */
	public boolean hasThumbnail(File f);

	/**
	 * @param f
	 * @return
	 * @throws VolumeIOException 
	 */
	public String getThumbnailUrl(File f) throws VolumeIOException;

	/**
	 * @return the max upload size in bytes
	 */
	public long getMaxUploadSize();
	
	/**
	 * @param newDir
	 * @throws VolumeIOException 
	 */
	public void createFolder(File newDir) throws VolumeIOException;

	/**
	 * @param newFile
	 * @throws VolumeIOException 
	 */
	void createFile(File newFile, ByteArrayOutputStream os) throws VolumeIOException;

	/**
	 * @param fileTarget
	 * @param futureFile
	 * @throws VolumeIOException 
	 */
	public void rename(File fileTarget, File futureFile) throws VolumeIOException;

	/**
	 * @param fileTarget
	 * @param futureFile
	 * @throws VolumeIOException 
	 */
	public void copy(File fileTarget, File futureFile) throws VolumeIOException;

	/**
	 * @param path
	 * @throws VolumeIOException 
	 */
	public void delete(File path) throws VolumeIOException;

	/**
	 * @return
	 */
	public long getTotalSize();

	/**
	 * @param value
	 * @param workingDirectory
	 * @param any
	 * @throws VolumeIOException 
	 */
	public File save(UploadedFile value, File workingDirectory, FileType type) throws VolumeIOException;

	/**
	 * @param value
	 * @param workingDirectory
	 * @throws VolumeIOException 
	 */
	public File save(UploadedFile value, File workingDirectory) throws VolumeIOException;

}
